import os
import time
import sys
import shutil

import where
import verbose

try:
    from pyrrd.rrd import RRD
except:
    print "Couldn't load required modules. You probably need to install it with:"
    sys.exit('sudo apt-get install python-pyrrd python-pysnmp4')

def graph_time_frames():
    return {  "1day":        24*60*60
             ,"1week":     7*24*60*60
             ,"1month":   31*24*60*60
#             ,"1hour":          60*60
             ,"1year":   365*24*60*60
#             ,"2years":2*365*24*60*60
           }

class RrdBase(object):
    def __init__(self, group, instance, domain):
        (self.atwork, self.atlaptop, self.atnas) = where.whereami()
        if self.atwork:
            self.base_dir = "/home/dschudel/file/Personal/rrd"
        elif self.atlaptop:
            self.base_dir = "/home/dan/file/rrd"
        elif self.atnas:
            self.base_dir = "/mnt/flash/local/rrd"

        self.perm_data_dir  = "{0}-data".format(self.base_dir)

        self.data_dir  = "/tmp/rrd/data"
        self.graph_dir = "/tmp/rrd/graphs/{0}/{1}/{2}".format(group, domain, instance)
        self.last_graph_time = self.graph_dir + "/lastrun"
        self.data_group = group
        self.data_instance = instance
        self.data_domain = domain
        self.filename       = "{0}/{1}.{2}.{3}.rrd".format(self.data_dir, self.data_domain, self.data_group, self.data_instance)
        self.perm_filename  = "{0}/{1}.{2}.{3}.rrd".format(self.perm_data_dir, self.data_domain, self.data_group, self.data_instance)
        self.check_and_create_file()
        self.myRRD = RRD(self.filename)

	# TODO: Nexus is 1280x800
	self.graph_width = 600
	self.graph_height= 600
	self.icon_width = 200
	self.icon_height= 200

        self.graph_step_times = {  "1day":self.data_step()
                                 ,"1hour":self.data_step()
                                 ,"1week":  1*60*60
                                 ,"1month": 6*60*60
                                 ,"1year": 24*60*60
                                 ,"2years":24*60*60
                                }

        self.grid             = {  "1day": '"HOUR:1:HOUR:1:HOUR:4:0:%a %R"'
                                 ,"1hour": '"MINUTE:1:MINUTE:15:MINUTE:15:0:%R"'
                                 ,"1week": '"HOUR:6:DAY:1:DAY:1:0:%a %R"'
                                 ,"1month":'"DAY:1:DAY:3:DAY:3:0:%m/%d"'
                                 ,"1year": '"MONTH:1:MONTH:1:MONTH:1:0:%b"'
                                 ,"2years":'"MONTH:1:MONTH:1:MONTH:1:0:%b"'
                                }

    def graph_time_frames(self):
        return graph_time_frames()

    def rrd_filename(self):
        return self.filename

    def image_name(self, tf):
        return "{0}/{1}.png".format(self.graph_dir, tf)

    def icon_name(self, tf):
        return "{0}/icon_{1}.png".format(self.graph_dir, tf)

    def rel_image_name(self, tf):
        return self.image_name(tf)[8:]

    def rel_icon_name(self, tf):
        return self.icon_name(tf)[8:]

    def rra_pattern(self):
        if self.data_step() == 300:
            # 1,600   = 2 days   of 5  minute samples
            # 6,700   = 2 weeks  of 30 minute averages
            # 24,775  = 2 months of 2  hour   averages
            # 288,797 = 2 years  of 24 hour   averages
            return ( (1,600), (6,700), (24,775), (288, 797) )
        elif self.data_step() == 60*60:
            # 1,48     = 2 days  of  1 hour samples
            # 3,56     = 1 week  of  3 hour averages
            # 24,365*2 = 2 years of 24 hour averages
            return ( (1,48), (3,56), (24,365*2))
        else:
            assert 0, "Unhandled data step {0}".format(self.data_step())

    def check_and_create_file(self):
        if False == os.path.isdir(self.data_dir):
            os.makedirs(self.data_dir)
        if False == os.path.isdir(self.perm_data_dir):
            os.makedirs(self.perm_data_dir)
        if False == os.path.isdir(self.graph_dir):
            os.makedirs(self.graph_dir)

        # if we have the file in perm, but not elsewhere, then copy from perm
        if os.path.isfile(self.perm_filename) and False == os.path.isfile(self.filename):
            import shutil
            shutil.copy(self.perm_filename, self.filename)

        if False == os.path.isfile(self.filename):
            self.create_file()

    def data_step(self):
        return 300

    def heartbeat(self):
        if self.data_step() == 300:
            return 600
        elif self.data_step() == 60*60:
            return 60*60 + 10*60
        else:
            return 2 * self.data_step()

    def graph(self):
#        assert 0, "RrdBase: graph() should not be called"
        pass

    def conditional_graph(self):
        need_graph = False
        if False == os.path.isfile(self.last_graph_time):
            need_graph = True
        else:
            then = os.stat(self.last_graph_time).st_mtime
            if time.time() - then > 60*60*2:
                n = time.localtime()
                if n.tm_hour == 5 or n.tm_hour == 12+4:
                    need_graph = True

        if need_graph:
            if verbose.verbose:
                print("Graphing {0}".format(self.filename))
            self.graph()
            open(self.last_graph_time, "w+")
            return True

        return False

    def conditional_update(self):
        now = time.time()
        then = os.stat(self.filename).st_mtime
        if (now - then < self.data_step() - 60):
            return
        else:
            if verbose.verbose:
                print("Updating {0}".format(self.filename))
            self.update()

        if os.path.isfile(self.perm_filename):
            # every 24 hours, sync to permanment store
            perm = os.stat(self.perm_filename).st_mtime
            if now - perm > (24*60*60):
                if verbose.verbose:
                    print("Sync to perm store (age) {0}".format(self.filename))
                shutil.copy(self.filename, self.perm_filename)
        else:
            if verbose.verbose:
                print("Sync to perm store (first) {0}".format(self.filename))
            shutil.copy(self.filename, self.perm_filename)

    def create_file(self):
        assert 0, "RrdBase: create_file() should not be called"

    def update(self):
        assert 0, "RrdBase: update() should not be called"
